import com.sun.jna.Pointer;

///The class implementing game play logic.
class AI extends BaseAI {

	private Board board;
	private SearchEngine searchEngine;

	public AI(Pointer c) {
		super(c);
	}

	//This function is called once, before your first turn
	public void init() { }

	//This function is called each time it is your turn
	//Return true to end your turn, return false to ask the server for updated information
	public boolean run() {		
		// Print out the current board state
		System.out.println("+---+---+---+---+---+---+---+---+");

		for(int rank = 8; rank > 0; rank--) {
			System.out.print("|");
			for(int file = 1; file <= 8; file++) {
				boolean found = false;
				// Loops through all of the pieces
				for(int p = 0; !found && p < pieces.length; p++) {
					// determines if that piece is at the current rank and file
					if(pieces[p].getRank() == rank && pieces[p].getFile() == file) {
						found = true;
						// Checks if the piece is black
						if(pieces[p].getColor() == Piece.COLOR_BLACK) {
							System.out.print("*");
						}else System.out.print(" ");

						// prints the piece's type
						System.out.print(pieces[p].toString() + " ");
					}
				}
				if(!found) System.out.print("   ");

				System.out.print("|");
			}
			System.out.println("\n+---+---+---+---+---+---+---+---+");
		}

		// Looks through information about the players
		for(int p = 0; p < players.length; p++) {
			System.out.print(players[p].getPlayerName());

			// if playerID is 0, you're white, if its 1, you're black
			if(players[p].getId() == playerID()) {
				System.out.print(" (ME)");
			}
			System.out.println(" time remaining: " + players[p].getTime());
		}

		// if there has been a move, print the most recent move
		if(moves.length > 0) {
			System.out.println("Last Move Was:\n" + moves[0]);
		}
		
		board = generateBoard(pieces, moves);
		
		movePiece();

		return true;
	}
	
	private void movePiece() {
		//searchEngine = new RandomSearchEngine(board);
		//searchEngine = new IterativeDeepeningDepthLimitedMinimaxSearchEngine(board);
		searchEngine = new IterativeDeepeningDepthLimitedMinimaxWithAlphaBetaPruningSearchEngine(board);
		searchEngine.execute(moves, pieces, getPlayerColor());
	}
	
	private Board generateBoard(Piece[] pieces, Move[] moves) {
		Board board = new Board(pieces, moves, getPlayerColor());
		board.setKingAttackers(board.isKingInCheck(getPlayerColor()));

		return board;
	}

	//This function is called once, after your last turn
	public void end() {}

	public String username() {
		return "Shell AI";
	}

	public String password() {
		return "password";
	}
	
	// instead of returning a simple raw integer, return the equivalent integer by
	// using the constants defined for the system. If someday, those constant values are
	// changed, there will be no need to update each and every reference to those values.
	public int getPlayerColor() {
		return (playerID() == 0 ? Piece.COLOR_WHITE : Piece.COLOR_BLACK);
	}
}
